<?php
///
namespace lxsphp\Core\Mvc;

///
use lxsphp\App;
use lxsphp\Load;

/**
 * 框架 - 消息调度器类
 *
 * @version $Id: Dispatcher.php 192 2014-07-18 02:27:45Z linsir123 $
 * @package lxsphp\Core\Mvc
 */
class Dispatcher
{
	/**
	 * 配置
	 *
	 * @var array
	 */
	public $conf = array();

	/**
	 * 控制器类名称
	 * // 首字大写
	 *
	 * @var string
	 */
	public $controller;

	/**
	 * 控制器方法名称
	 * // 首字大写
	 *
	 * @var string
	 */
	public $action;

	/**
	 * 构造函数
	 */
	public function __construct()
	{
		///
		$this->conf = App::o("app.dispatcher");
	}

	/**
	 * 运行指定的控制器方式
	 *
	 * @param string $controller 控制器名
	 * @param string $action 方法名
	 * @param bool $inBase 异常跳转使用$app目录，不使用到$appSub
	 */
	public function doController($controller, $action, $inBase = false)
	{
		///
		list($dir, $nameSpace) = $this->_getRelInfo($inBase);
		$controller = $controller ? : $this->conf['defaultController'];
		$controller = ucfirst($controller);
		$class = $nameSpace . $controller;

		///
		if (! class_exists($class, false)) {
			$file = sprintf("%s.php", $controller);

			if (! Load::file($file, $dir, false))
				$this->_miss("The Controller file({$file}) is miss.");

			if (! class_exists($class, false))
				$this->_miss("The Controller class({$class})is miss.");
		}

		///
		$this->controller = $controller;
		$this->action = $action;

		/**
		 * @var \lxsphp\Core\Mvc\Controller $o
		 */
		$o = App::$I->singleton($class);
		$data = $o->doAction($controller, $action);
		if (! $data[0])
			$this->_miss($data[1]);
	}

	/**
	 * 取得控制器目录
	 *
	 * @param bool $inBase 异常跳转使用$app目录，不使用到$appSub
	 *
	 * @return array
	 * @example array($dir, $nameSpace)
	 */
	private function _getRelInfo($inBase)
	{
		///
		list($app, $appSub) = App::$I->alias;

		$v = 'Controller/'
			. (! empty($app) ? (ucfirst($app) . '/') : '')
			. (! empty($appSub) && ! $inBase ? (ucfirst($appSub) . '/') : '');

		///
		return array(
			APP_DIR . $v,
			"app\\" . str_replace('/', '\\', $v)
		);
	}

	/**
	 * 直接抛出系统异常,由系统进行系统自定义控制器的调度
	 *
	 * @param string $message 异常描述
	 *
	 * @throws \Exception
	 */
	private function _miss($message)
	{
		///
		App::$I->getHandler()->panic($message, 404);
	}
}
